package db

import (
	"errors"
	"fmt"
	"go.uber.org/zap"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"lib/config"
	zapLog "lib/log"
	"log"
	"os"
	"strings"
	"time"
)

var _db *gorm.DB

// Gorm 初始化数据库并产生数据库全局变量
func InitGorm(mcf *config.Mysql) error {
	if mcf == nil || mcf.Dbname == "" {
		return errors.New("数据库Name不能为空")
	}
	mysqlConfig := mysql.Config{
		DSN: mcf.Dsn(), // DSN data source name
	}

	gormConfig := &gorm.Config{DisableForeignKeyConstraintWhenMigrating: true}
	_default := logger.New(newWriter(mcf, log.New(os.Stdout, "\r\n", log.LstdFlags)), logger.Config{
		SlowThreshold: 200 * time.Millisecond,
		LogLevel:      logger.Warn,
		Colorful:      true,
	})
	switch strings.ToLower(mcf.LogMode) {
	case "silent":
		gormConfig.Logger = _default.LogMode(logger.Silent)
	case "error":
		gormConfig.Logger = _default.LogMode(logger.Error)
	case "warn":
		gormConfig.Logger = _default.LogMode(logger.Warn)
	case "info":
		gormConfig.Logger = _default.LogMode(logger.Info)
	default:
		gormConfig.Logger = _default.LogMode(logger.Info)
	}
	tdb, err := gorm.Open(mysql.New(mysqlConfig), gormConfig)
	if err != nil {
		return err
	}
	sqlDB, err := tdb.DB()
	if err != nil {
		return err
	}
	sqlDB.SetMaxIdleConns(mcf.MaxIdleConnections)
	sqlDB.SetMaxOpenConns(mcf.MaxOpenConnections)
	sqlDB.SetConnMaxLifetime(25000 * time.Second)

	if mcf.LogZap {
		_db = tdb.Debug()
	} else {
		_db = tdb
	}

	return nil
}

func GetDb() *gorm.DB {
	return _db
}

type Writer struct {
	conf *config.Mysql
	logger.Writer
}

// NewWriter writer 构造函数
func newWriter(conf *config.Mysql, w logger.Writer) *Writer {
	return &Writer{Writer: w, conf: conf}
}

// Printf 格式化打印日志
func (w *Writer) Printf(message string, data ...interface{}) {
	logZap := w.conf.LogZap
	if logZap {
		zapLog.Info(fmt.Sprintf(message+"\n", data...), zap.Namespace(""))
	} else {
		w.Writer.Printf(message, data...)
	}
}
